package index;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import net.barashev.seclub.corpus.Corpus;
import net.barashev.seclub.corpus.wikipedia.WikipediaFileCorpus;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import stemmer.PorterStemmer;
import stemmer.PorterStemmerExeption;

public class XML_Informational {

    private static final String DELIM = "\t\b\n\r\f\'\"\\ "
            + ";:{}?[]?/.,<>~`!@#$%^&*()_-+=|" + "1234567890";
    private static final String TAG_BODY = "body";
    private static final String TAG_TITLE = "title";
    private static final Set<Character> GOOD_SYMBOLS = new HashSet<Character>();
    private List<String> termsInBody = new ArrayList<String>();
    private List<String> termsInTitle = new ArrayList<String>();
    private boolean parsingWithoutExceptions = true;

    static {
        GOOD_SYMBOLS.add('a');
        GOOD_SYMBOLS.add('b');
        GOOD_SYMBOLS.add('c');
        GOOD_SYMBOLS.add('d');
        GOOD_SYMBOLS.add('e');
        GOOD_SYMBOLS.add('f');
        GOOD_SYMBOLS.add('g');
        GOOD_SYMBOLS.add('h');
        GOOD_SYMBOLS.add('i');
        GOOD_SYMBOLS.add('j');
        GOOD_SYMBOLS.add('k');
        GOOD_SYMBOLS.add('l');
        GOOD_SYMBOLS.add('m');
        GOOD_SYMBOLS.add('n');
        GOOD_SYMBOLS.add('o');
        GOOD_SYMBOLS.add('p');
        GOOD_SYMBOLS.add('q');
        GOOD_SYMBOLS.add('r');
        GOOD_SYMBOLS.add('s');
        GOOD_SYMBOLS.add('t');
        GOOD_SYMBOLS.add('u');
        GOOD_SYMBOLS.add('v');
        GOOD_SYMBOLS.add('w');
        GOOD_SYMBOLS.add('x');
        GOOD_SYMBOLS.add('y');
        GOOD_SYMBOLS.add('z');

    }

    public XML_Informational(String content) {
        // content = "DataForCorpus/";
        // uri+="example.xml";
        // content+="matan.txt";
        Document document = parseXML(content);

        if (parsingWithoutExceptions) {
            Element root = document.getDocumentElement();
            PorterStemmer porterStemmer = new PorterStemmer();
            createTermsInBody(root, porterStemmer);
            createTermsInTitle(root, porterStemmer);
        }
    }

    private void createTermsInTitle(Element root, PorterStemmer porterStemmer) {
        createTermsIn(TAG_TITLE, root, porterStemmer);

    }

    private void createTermsInBody(Element root, PorterStemmer porterStemmer) {
        createTermsIn(TAG_BODY, root, porterStemmer);
    }

    private void createTermsIn(String tag, Element root,
            PorterStemmer porterStemmer) {
        NodeList nodeListBody = root.getElementsByTagName(tag);
        // for (int i = 0; i < nodeListBody.getLength(); i++) {
        assert nodeListBody.getLength() == 1;
        String text = nodeListBody.item(0).getTextContent();

        for (StringTokenizer textTkz = new StringTokenizer(text, DELIM); textTkz
                .hasMoreElements();) {
            String token = textTkz.nextToken();
            token = minusCaseChar(token);
            if (!Indexator.BAN_LIST_TOKENs.contains(token)) {
                String term = null;
                try {
                    term = porterStemmer.stem(token);

                } catch (PorterStemmerExeption e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                term = checkOnCorrectness(term);
                if (term != null) {
                    assert !"".equals(term);
                    addTermIn(tag, term);
                }
            }
        }
        // }
    }

    /**
     * forced checking
     *
     * @param term
     * @return
     */
    private String checkOnCorrectness(String term) {
        if (term != null) {
            char[] c = term.toCharArray();
            for (int i = 0; i < c.length; i++) {
                if (!GOOD_SYMBOLS.contains(c[i])) {
                    //System.out.println("UnCorrect term "+ term);
                    return null;
                }
            }
        }
        return term;
    }

    private void addTermIn(String tag, String term) {
        if (tag.equals(TAG_BODY)) {
            termsInBody.add(term);
            return;
        }
        if (tag.equals(TAG_TITLE)) {
            termsInTitle.add(term);
            return;
        }
        try {
            throw new MyExeption("USED UNCORRECT TAG");
        } catch (MyExeption e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private String minusCaseChar(String term) {
        char[] chars = term.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            chars[i] = Character.toLowerCase(chars[i]);
        }
        return new String(chars);
    }

    private Document parseXML(String content) {
        Document document = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder;
        try {
            builder = factory.newDocumentBuilder();
            // document = builder.parse(uri);
            InputSource inputSource = new InputSource(new StringReader(content));
            document = builder.parse(inputSource);
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            System.out
                    .println("Content is not correction - SAXException in class XML_Informational. Msg:");
            System.out.println(e.getMessage());
            System.out.println();
            parsingWithoutExceptions = false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return document;
    }

    public List<String> getTermsInBody() {
        return termsInBody;
    }

    public List<String> getTermsInTitle() {
        return termsInTitle;
    }
}
